package org.example.springtrans.controller;

import org.example.springtrans.mapper.UserInfoMapper;
import org.example.springtrans.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

/**
 * 声明式事务
 */
@RestController
@RequestMapping("/trans")
public class TransController {
    private static final Logger log = LoggerFactory.getLogger(TransController.class);
    @Autowired
    private UserService userService;
    // 在目标方法执行前，自动开启事务，目标方法执行完成后，自动提交事务
    // 如果方法执行过程中，出现异常，且没有捕获，就会进行事务回滚
    // 如果异常被程序捕获，方法就被认为是正常执行，依然会提交事务
    // 如果将异常抛出去，依然会进行事务回滚操作
    @Transactional
    @RequestMapping("register")
    public String register(String username, String password) {
        // 用户注册
        userService.register(username, password);
        log.info("用户数据插入成功");
        // 对异常进行捕获
        try {
            // 强制程序抛出异常
            int n = 10/0;
        } catch (Exception e) {
            // 重新抛出异常   事务回滚
//            throw new RuntimeException(e);
            // 手动设置事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        return "注册成功";
    }

    // @Transactional 默认只在遇到运行时异常和Error时才会回滚
    // 通过配置 rollbackFor 属性指定发生哪种异常类型进行回滚
    @Transactional(rollbackFor = Exception.class)
    @RequestMapping("/r2")
    public String r2(String username, String password) throws IOException {
        userService.register(username, password);
        log.info("用户数据插入成功");
        if(true) {
            throw new IOException();
        }
        return "注册成功";
    }

    @Transactional(isolation = Isolation.READ_COMMITTED)
    @RequestMapping("/r3")
    public String r3(String username, String password) throws IOException {
        userService.register(username, password);
        log.info("用户数据插入成功");
        return "注册成功";
    }

}
